Status

Aug 16, 2024 (but writing these notes after midnight, so august 17th technically)

I think I finished the security apparatus of the initialization page. I also added database initialization.

The initialization script requires the pin file to exist, to contain a pin from 20-40 characteres, and have no users exist in the database. If a PDO exception is thrown, the script fails, unless the error message contains SQLSTATE[42S02] for the table not existing.

For changes to be saved, the stored pin must be POSTed through the form, and the initialization pin file must be successfully deleted.

The script definitely needs to be double-checked for errors, and maybe triple-checked.

I'm not actually sure how to use the logged in user on the site. I need to document that. I think I implemented it last time.

I also just need to document the entire new setup process.

Aug 15, 2024

Building initialization feature & easy server setup to have a fully functional user login gui with very little setup. I stopped midwork because it's late. I was working in the initialize page to handle database initialization, but I got an error about the tables not existing. So I separated user login into get_user() in EasyServer, which will probably work, but then I just got stuck thinking about if I need to modify the deliver script & if I need to control for the specific page url ... i just got stuck mentally so I'm stopping.

Files made:

  • public/@POST.@GET.initialize.php
  • code/class/EasyServer.php
  • test/EasySetup/*

Dec 8, 2022

  • Upgrading to work with php8.2
  • Working on tests (DONE)ThrottleLoginUser and (DONE)Server,
  • the cookie expires string from setcookie() uses the format D, d-M-Y H:i:s e in php8.1, but uses D, d M Y H:i:s e in php 8.2

May 4, 2022

  • special, brief T&Cs for login & password reset

Things

  • re-build sql
  • bin/tlfuser build to serialize the sql files
  • bin/tlfuser init to create the user database, loading db settings from .config/env.json

Tests TODO

  • test that $user->all_roles returns a role even if there are no associated permissions

Versions

  • v0.1: old version, old Liaison
  • v0.2: New version, liaison v0.5
  • v0.3: Removing Sentinel dependency

TODO MVP

  • add roles with no permissions to list of roles on user profile page

  • delete all the old code

  • MAYBE easy way to delete expired throttles & expired codes (for cron jobs)

  • add cookie info to the terms & conditions

  • add a help page

  • make compatible with liaison v0.6??

  • add easy liaison/server integration

  • DONE $lib->role_deny('role', 'permission') and $lib->role_delete('role'), then add it to the docs test & main tests

  • DONE basic README

  • DONE t&c + privacy policy

  • DONE disable pages

  • DONE csrf tokens: See https://www.taeluf.com/blog/php/security/csrf-validation/ for my notes

    • DONE request password
    • DONE complete password
    • DONE register
    • DONE login (validation engine + csrf)
  • DONE UPDATE enable_csrf() to actually generate a random code

  • DONE disable forced csrf approval when user agent is present (so i can properly test csrf in the browser) & properly test csrf in the browser

  • DONE simple 'profile' page

    • DONE email
    • DONE permissions, roles
    • DONE change password button (takes you to reset password page)
    • DONE security history (logins, password resets, registration, ...)
    • DONE link to terms & conditions
  • DONE /user/ should redirect to profile page or login page

  • DONE log actions:

    • DONE emails being sent (probably?)
    • DONE terms & conditions agreement
    • DONE login
    • DONE register (this presumes full T&C have been agreed to)
    • DONE complete registration (landing on the page)
    • DONE request password reset
    • DONE complete password reset (this presumes registration has been completed & full t&c were agreed to)
      • DONE submitting the form
      • NO landing on the page? probably ... no, not for landing on the page, only for submitting the form
  • DONE basic spam control:

    • DONE honey pot
    • DONE generate code & auto-fill with js (plus <noscript> for folks who need it)
  • DONE Polishy things

    • DONE /user/login/ should show logout link if currently logged in
    • DONE logout page should have link to login
    • DONE show password requirements on register & set new password page
    • DONE terms & conditions checkbox on register page
    • DONE check if user is currently logged in & redirect or provide link and/or message as needed
      • DONE registration page
      • DONE login page
    • DONE log better messages like "login failed" or "registration failed" ... Maybe "login attempt" followed by "successful login"?? Or just write a message on the profile page that tells you the logging is bad lol
    • NO in email sent to complete registration & to complete password reset, include message about security logging (or don't because that's part of the greater T&Cs when you register & you only get a link if your account is active) ... not changing the email content bc the security logging is covered by the terms & conditions when registering

TODO eventually

  • DONE convert login to validation engine
  • Testing
    • when mail() returns false (this theoretically shouldn't happen, but still...)
    • /user/ redirects properly
    • /user/profile/ displays 'not logged in' message + links
    • /user/profile/ displays permissions & security & stuff
    • logging in general
  • GUI stuff
    • edit user form (change email? shoot ... that might be a future feature)
    • admin/user-management (may be able to defer this & rely on backend setup code)
      • enable/disable registration
      • create user
      • delete user
      • create/delete role
      • add role to user
      • add permission to role
      • add permission to user
      • remove role from user
      • remove permission from user

Niceties that I'm putting off

  • an sql file that holds all the sql queries, generated by LilSql
  • A 'messages' file that holds all the messages we send to users. Then allow the messages to be modified by the programmer. Use sprintf(), probably to fill in certain details like email addresses & urls. Or maybe use a lazy binding method like preg matching :some_key type of thing
  • LATER pre-fetch permissions for a user. Probably LIMIT 100? Or MAYBE only load role-based permissions, as that will be a shorter and more frequently used list. I'm trying to minimize db round trips, especially in production where the database is over IP.
  • LATER add error reporting? (just simple callback function)
  • LATER validate the code type passed to new_code() (like using an enum ...)
  • LATER normalize the password hashing into a method
  • LATER rethink is_active for the code table ... it semantically is meh
    • password_reset: is active once the password is successfully reset
    • login_cookie: is active as soon as it's created
    • registration: is active once registration is completed
      • but "is active" should mean "is the code active", which means "can the code be used" ... which kinda means that registration & password_reset should start active & then be de-activated (as should login_cookie)
      • this isn't super important, as long as I document & test. It would be nice to have semantic intuitiveness though
  • LATER maybe register() should return a code for registration
  • LATER a simple/small framework for writing named sql queries in an sql file & loading them dynamically into php. Something like ;;;QUERY_NAME then the query starts on the next line. This would be some overhead, but would be nice for portability & would allow me to dynamically EXPLAIN any query. Alternatively, I could just wrap my pdo prepare() call in a method that can add EXPLAIN for debugging/optimizing